/*
 * 2012.2
 * wicknec
 * DrawCNT
 *
 */
module DrawCNT
{
#include "ldata.h"
#include <stdlib.h>
#include <math.h>
char SBuffer[9999]; 
char AtoFBuffer[100];
LPoint PointArray[100];

	//Ask about the data of CNT and return in SBuffer
	//LDialog can hold no more than 255 bytes
	void AskForData(const char* title)
	{
		LDialog_InputBox(title,"please input the data",SBuffer);
	}
	//convert the followed numbers to double until a space or \n or ;
	//return the length of consumed string
	double AtoFNow(char* curpos,int* len)
	{
		int length = 0;
		int whiteLength = 0;
		while(*curpos == ' ')
		{
			whiteLength++;
			curpos++;
			if(*curpos == '\0')
			{
				*len = -1;
				return 0;
			}
		}
		while((*curpos >= '0' && *curpos <= '9') || 
				*curpos == '.' || *curpos == '-' || 
				*curpos == '+')
		{
			AtoFBuffer[length] = *curpos;
			length++;
			curpos++;
		}
		AtoFBuffer[length] = '\0';
		(*len) = length + whiteLength;
		return atof(AtoFBuffer);
	}
	//process one vertex with the format
	//returns the next position in the row
	// format: __1__x__y(\n|;)...
	char* ProcessOneLine(char* curpos, LPoint* p)
	{
		int length = 0;
		AtoFNow(curpos,&length);
		curpos += length;
		(*p).x = AtoFNow(curpos,&length)*1000;
		curpos += length;
		(*p).y = AtoFNow(curpos,&length)*1000;
		curpos += length;
		if(length == 0)
			return curpos;// illegal format
		if(*curpos == '\n' || *curpos == ';')
			curpos++;
		if(*curpos == '\r' || *curpos == ';')
			curpos++;
		if(*curpos == '\n' || *curpos == ';')
			curpos++;
		return curpos;
	}
	void SetMsgNum(int n)
	{
		itoa(n,AtoFBuffer,10);
		LStatusBar_SetMsg(AtoFBuffer);
	}
	void BoxMsgNum(int n)
	{
		itoa(n,AtoFBuffer,10);
		LDialog_MsgBox(AtoFBuffer);
	}
	void ShowNumber(void)
	{
		int length = 0;
		AskForData("  A Number");
		length = (int)AtoFNow(SBuffer,&length);
		SetMsgNum(length);
	}
	//return ==p if *p doesn't start with cstr
	//else returns the pointer immediately after cstr
	char* StrStartsWith(char* p,char* cstr)
	{
		int idx = 0;
		for(p;p[idx] != '\0' && cstr[idx] != '\0';idx++)
			if(p[idx] != cstr[idx])
				break;
		if(cstr[idx] == '\0')
			return p+idx;
		else
			return p;
	}
	//read the format and draw the line
	//the format is like <white spaces><number:point number:no use><white spaces>
	//<number:x><whitespaces><number:y><\n or ;>...until the end
	char* DrawLine(char* curpos)
	{
		int pointIndex = 0;
		char* tp;
		LCoord width = 1;
		LWindow pWindow = LWindow_GetVisible();
		LStatusBar_SetMsg("Loo and behold!");
		//BoxMsgNum(strlen(SBuffer));
		tp = StrStartsWith(curpos,"\\width{");
		if(tp != curpos)
		{
			//then is a command to set line width
			curpos = tp;
			//borrow pointIndex for a moment to store number length;
			width = AtoFNow(curpos,&pointIndex)*1000;
			curpos += pointIndex+1;
			pointIndex = 0;
		}
		while(*curpos == ' ')
		{
			curpos = ProcessOneLine(curpos,PointArray+pointIndex);
			pointIndex++;
		}
		//BoxMsgNum((int)(PointArray[1].x));
		//BoxMsgNum((int)(PointArray[1].y));

		if(Assigned(pWindow))
		{
			LCell pCell = LWindow_GetCell(pWindow);
			LFile pFile = LWindow_GetFile(pWindow);
			
			if(Assigned(pCell) && Assigned(pFile))
			{
				LLayer pLayer = LLayer_GetCurrent(pFile);
				if(Assigned(pLayer))
				{
					LWireConfig c;
					LObject pO;
					c.width = width;
					pO = LWire_New(pCell,pLayer,&c,1,PointArray,pointIndex);
					if(!Assigned(pO))
						LDialog_MsgBox("Something is wrong, wire not drawn.");
					else
					{
						LCell_SetView(pCell,LObject_GetMbb(pO));
						BoxMsgNum(pointIndex);
					}

				}
				else
					LDialog_MsgBox("Layer is not assigned");
			}
			else
				LDialog_MsgBox("Cell is not assigned");
		}
		return curpos;
	}
	void AskDrawCNT(void)
	{
		char* tp,
			*curpos = SBuffer;
		AskForData("Layer Code");
		tp = StrStartsWith(curpos,"\\PolyLine");
		while(tp != curpos)
		{
			curpos = tp;
			curpos = DrawLine(curpos);
			curpos = StrStartsWith(curpos,"\\endPolyLine");
			tp = StrStartsWith(curpos,"\\PolyLine");
		}

	}
	void AskDrawLine(void)
	{
		AskForData("Line Vertices");
		DrawLine(SBuffer);
	}

	void DrawCNT_register(void)
	{
		LMacro_Register("AskDrawLine","AskDrawLine");
		LMacro_BindToMenu("Tools","DrawLine","AskDrawLine");
		LMacro_BindToHotKey(KEY_F4,"DrawLine","AskDrawLine");
		LMacro_Register("Show Number","ShowNumber");
		LMacro_Register("AskDrawCNTs","AskDrawCNT");
	}
}/* End of Module */
DrawCNT_register();

